
const URL = require('url')
const WebSocket = require('ws')
// const { expressjwt: jwt } = require('express-jwt')
const jwt = require('jsonwebtoken')

const config = require('../config.js')


let server = null, wss = null, userConnections = null

// 处理升级请求（验证 Token）
const handleUpgrade = (request, socket, head) => {
    // const authHeader = request.headers.authorization
    let token = null
    const parsedUrl = URL.parse(request.url, true)

    // 从查询参数中获取 Token
    token = parsedUrl.query.token

    // 从请求头获取 Token
    // if (authHeader && authHeader.startsWith('Bearer ')) {
    //     token = authHeader.split(' ')[1]
    // }

    if (!token) {
        console.log('wss token 认证失败', parsedUrl)
        socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n')
        socket.destroy()
        return
    }

    // 验证 Token
    try {
        const decoded = jwt.verify(token, config.jwtSecretKey, {
            algorithms: ['HS256']
        })

        // 验证通过，保存用户信息并升级连接
        request.user = decoded
        wss.handleUpgrade(request, socket, head, (ws) => {
            wss.emit('connection', ws, request)
        })
    } catch (error) {
        console.error('Token 验证失败:', error.message)
        socket.write('HTTP/1.1 403 Forbidden\r\n\r\n')
        socket.destroy()
    }
}

// 处理连接建立
const handleConnection = (ws, request) => {
    const uid = request.user.uid

    // 顶号
    disconnectUser(uid, '顶号')
    // 存储用户连接
    userConnections.set(uid, ws)
    console.log(`用户 ${uid} 连接, 当前在线: ${userConnections.size}`, getOnlineUsers())

    // 处理收到的消息事件
    ws.on('message', (data) => {
        handleMessage(ws, data, uid)
    })

    // 处理连接关闭
    ws.on('close', () => {
        if (userConnections.get(uid) === ws) {
            userConnections.delete(uid)
        }

        console.log(`用户 ${uid} 断开, 当前在线: ${userConnections.size}`, getOnlineUsers())
    })

    // 处理错误
    ws.on('error', (error) => {
        console.error(`用户 ${uid} 连接错误:`, error)
    })
}

const disconnectUser = (userId, reason = '正常关闭', code = 1000) => {
    const ws = userConnections.get(userId)
    if (ws && ws.readyState === WebSocket.OPEN) {
        // 发送最后的通知消息（可选）
        ws.send(JSON.stringify({
            event: 'close',
            eventContent: `服务器断开连接: ${reason}`,
        }))


        ws.close(code, reason)
        console.log(`已主动断开用户 ${userId} 的连接，代码: ${code}, 原因: ${reason}`)

    }
}

// 处理事件消息
const handleMessage = (ws, data, srcUid) => {
    try {
        const eventMessage = JSON.parse(data)
        if (!eventMessage.event || !eventMessage.eventContent) {
            return ws.send(JSON.stringify({
                event: 'error',
                eventContent: '无效的事件消息格式'
            }))
        }
        const { event, eventContent } = eventMessage
        // sendMessage事件
        if (event === 'sendMessage') {
            if (eventContent.targetUid && eventContent.content) {
                const sendData = {
                    srcUid,
                    targetUid: eventContent.targetUid,
                    content: eventContent.content,
                    time: new Date().toISOString(),
                    type: 'commonMsg'
                }
                return sendToUser(eventContent.targetUid, {
                    event: 'receiveMessage',
                    eventContent: sendData
                })
            } else {
                return ws.send(JSON.stringify({
                    event: 'error',
                    eventContent: '无效的消息格式'
                }))
            }
        }
    } catch (error) {
        console.error('ws解析事件消息失败:', error)
        ws.send(JSON.stringify({
            event: 'error',
            eventContent: {
                msg: 'ws解析事件消息失败:',
                error
            }
        }))
    }
}


// 向指定用户发送消息
const sendToUser = (targetUid, sendData) => {
    const targetWs = userConnections.get(targetUid)
    if (targetWs && targetWs.readyState === WebSocket.OPEN) {
        targetWs.send(JSON.stringify(sendData))
        return true
    }
    return false
}

// 获取所有在线用户ID
const getOnlineUsers = () => {
    return Array.from(userConnections.keys())
}

const initWebSocketServer = (httpsServer) => {
    server = httpsServer
    wss = new WebSocket.Server({ noServer: true })
    userConnections = new Map() // 存储用户连接: uid -> WebSocket

    // 挂载wss服务
    // 处理 HTTP 升级请求
    server.on('upgrade', (request, socket, head) => {
        handleUpgrade(request, socket, head)
    })
    // 处理 WebSocket 连接
    wss.on('connection', (ws, request) => {
        handleConnection(ws, request)
    })

    return {
        getOnlineUsers
    }

}

module.exports = { initWebSocketServer }